﻿// test.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//对示例程序的解析

#include "pch.h"
#include <iostream>
#include <Audiopolicy.h>
#include <Audioclient.h>
#include <MMDeviceAPI.h>
#include <vector>

//参考时间，每秒和每毫秒的时间单位
const REFERENCE_TIME REFTIMES_PER_SEC = 10000000;
const REFERENCE_TIME REFTIMES_PER_MILLISEC = 10000;


int main()
{

	HRESULT hr;

	hr = CoInitializeEx(NULL, COINIT_MULTITHREADED);//在当前线程上初始化 COM 库

	const CLSID CLSID_MMDeviceEnumerator = __uuidof(MMDeviceEnumerator);//获取类的UUID
	const IID IID_IMMDeviceEnumerator = __uuidof(IMMDeviceEnumerator);//获取接口的UUID
	const IID IID_IAudioClient = __uuidof(IAudioClient);
	const IID IID_IAudioCaptureClient = __uuidof(IAudioCaptureClient);

	//创建多媒体设备枚举器
	IMMDeviceEnumerator *pEnumerator = NULL;
	hr = CoCreateInstance(
		CLSID_MMDeviceEnumerator, NULL,
		CLSCTX_ALL, IID_IMMDeviceEnumerator,
		(void**)&pEnumerator);

	boolean a = FAILED(hr);

	//获取声卡接口
	IMMDevice *pDevice = NULL;
	pEnumerator->GetDefaultAudioEndpoint(eRender, eConsole, &pDevice);

	//通过声卡接口获取声卡客户端接口
	IAudioClient *pAudioClient = NULL;
	pDevice->Activate(IID_IAudioClient, CLSCTX_ALL, NULL, (void**)&pAudioClient);


	//获取音频格式
	WAVEFORMATEX *pwfx = NULL;
	pAudioClient->GetMixFormat(&pwfx);
	//初始化声卡客户端
	REFERENCE_TIME hnsRequestedDuration = REFTIMES_PER_SEC; //采样持续时间，单位100纳秒
	pAudioClient->Initialize(
		AUDCLNT_SHAREMODE_SHARED,//与其他设备共享音频端点设备
		0,//选项
		hnsRequestedDuration,//以时间值表示的缓冲区容量
		0,//设备周期，共享模式下设为0
		pwfx,//音频格式
		NULL//指向session的GUID的指针，设置为NULL表示打开一个新session
	);

	//获取缓冲区大小（有多少音频帧）
	UINT32 bufferFrameCount;
	pAudioClient->GetBufferSize(&bufferFrameCount);

	//获取捕获客户端
	IAudioCaptureClient *pCaptureClient = NULL;
	hr = pAudioClient->GetService(IID_IAudioCaptureClient, (void**)&pCaptureClient);

	//开始记录
	//计算所分配缓冲区的实际持续时间
	REFERENCE_TIME hnsActualDuration = (double)REFTIMES_PER_SEC * bufferFrameCount / pwfx->nSamplesPerSec;

	pAudioClient->Start();
	
	UINT32 packetLength = 0;//数据包大小
	BYTE *pData;//指向数据包首地址的指针
	UINT32 numFramesAvailable;//用于接收数据包中可用的音频帧数
	DWORD flags;//缓冲区状态标志

	std::vector<BYTE> body;//数据体

	int recordCount = 20;
	while (recordCount>0)
	{
		// 在缓冲期的一半时间内睡眠
		//Sleep(hnsActualDuration / REFTIMES_PER_MILLISEC / 2);
		pCaptureClient->GetNextPacketSize(&packetLength);
		while (packetLength != 0)
		{
			//获取下一个数据包
			pCaptureClient->GetBuffer(
				&pData,//数据包指针变量的地址
				&numFramesAvailable, //数据包中可用的音频帧数
				&flags, //缓冲区状态标志
				NULL,
				NULL
			);

			if (flags & AUDCLNT_BUFFERFLAGS_SILENT)
			{
				pData = NULL;  // 判断是否静音
			}

			int dataSize = numFramesAvailable * 4;//可用帧数*4=BYTE数

			for (int i = 0; i < dataSize; i++)
			{
				BYTE tem = pData[i];
				body.push_back(pData[i]);
			}
		}
	}

	for (int i = 0; i < body.size(); i++)
	{
		printf("%d\n", body[i]);
	}

}


